Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by www.netzwerkartist.de...

 << zurück
Visual C# 2005 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2005

Visual C# 2005
1.320 S., mit 2 CDs, 59,90 Euro
Galileo Computing
ISBN 3-89842-586-X
gp Kapitel 15 Grundlagen zum Erstellen einer Windows-Anwendung
  gp 15.1 Die Entwicklungsumgebung
  gp 15.2 Eine erste Windows-Anwendung
  gp 15.3 Das Codegerüst einer Windows-Anwendung
    gp 15.3.1 Die Datei »Program.cs«
    gp 15.3.2 Die Dateien »Form1.cs« und »Form1.Designer.cs«
  gp 15.4 Ereignisse grafischer Windows-Komponenten
    gp 15.4.1 Grundlegende Anmerkungen
    gp 15.4.2 Ereignisse mit Ereignisdaten
    gp 15.4.3 Ereignishandler mit dem Visual Studio 2005 bereitstellen
    gp 15.4.4 Ereignisbehandlung mit den »OnXxx«-Methoden
  gp 15.5 Die Basisklassen einer Form
    gp 15.5.1 Die Klasse »Control«
    gp 15.5.2 Die Klasse »ScrollableControl«
    gp 15.5.3 Die Klasse »ContainerControl«
  gp 15.6 Die Eigenschaften einer Form
    gp 15.6.1 Die Rahmendarstellung einer Form
    gp 15.6.2 Formspezifisches Symbol festlegen
    gp 15.6.3 Die Schaltflächen in der Titelleiste
    gp 15.6.4 Spielereien mit »Opacity« und »TransparencyKey«
    gp 15.6.5 Fenster, die nicht verdeckt werden können
    gp 15.6.6 Den Mauszeiger verändern
    gp 15.6.7 Farbeinstellungen mit dem Typ »Color«
    gp 15.6.8 Schriftart mit dem Typ »Font«
    gp 15.6.9 Die Abmessungen einer Form festlegen
    gp 15.6.10 Die Position eines Fensters
    gp 15.6.11 Der Anzeigezustand eines Fensters nach dem Öffnen
    gp 15.6.12 Die Arbeitsfläche des Fensters (der Clientbereich)
    gp 15.6.13 Die Auflistung »ControlsCollection«
    gp 15.6.14 Zusammenfassung der Eigenschaften des Form-Objekts
  gp 15.7 Ereignisse einer Form
    gp 15.7.1 Ereignisse beim Erzeugen eines Fenster
    gp 15.7.2 Größenänderung einer Form
    gp 15.7.3 Ereignisse beim Schließen eines Fensters
  gp 15.8 Anwendungen mit mehreren Fenstern
    gp 15.8.1 Neue Forms hinzufügen
    gp 15.8.2 Formulare laden, anzeigen, verstecken und schließen
    gp 15.8.3 Mehrere Fenster verwalten
    gp 15.8.4 Formulare in einem eigenen Thread laufen lassen
    gp 15.8.5 Splash-Fenster
  gp 15.9 Modale Dialogfenster
    gp 15.9.1 Layout eines Dialogfensters
    gp 15.9.2 Die Eigenschaft »DialogResult«
    gp 15.9.3 Eine Form modal öffnen
    gp 15.9.4 Die Weitergabe von Resultaten aus einem Dialog
    gp 15.9.5 Dialoge mit einer »Übernehmen«-Schaltfläche
    gp 15.9.6 Fokussierreihenfolge und Standardschaltflächen
  gp 15.10 Meldungsfenster mit »MessageBox«
    gp 15.10.1 Die Methode »MessageBox.Show«
    gp 15.10.2 Der Rückgabewert der Meldungsfenster
  gp 15.11 Das Speichern in der Registrierungsdatenbank
    gp 15.11.1 Die Klassen »Registry« und »RegistrKey«
    gp 15.11.2 Programmbeispiel zum Speichern in der Registrierung
  gp 15.12 Die Klasse »Application«
    gp 15.12.1 Die Datei »AssemblyInfo.cs«
    gp 15.12.2 Mit »Application.DoEvents« wartende Ereignisse abrufen
    gp 15.12.3 Zusammenfassung Eigenschaften und Methoden


Galileo Computing

15.3 Das Codegerüst einer Windows-Anwendundowntop

In Abbildung 15.5 sehen Sie den Inhalt des Projektmappen-Explorers der Anwendung, die wir eben erstellt haben.

Abbildung
Hier klicken, um das Bild zu vergrößern

Abbildung 15.5   Projektmappen-Explorer des Projekts »FirstApplication«

Es fällt auf, dass wir es mit drei Sourcecode-Dateien zu tun haben:

gp  Form1.cs
gp  Form1.Designer.cs
gp  Program.cs

Galileo Computing

15.3.1 Die Datei »Program.cs«  downtop

Hier zunächst der Inhalt der zuletzt genannten Datei.


static class Program {
  static void Main() {
    Application.EnableVisualStyles();
    Application.Run(new Form1());
  }
}

Der Code erinnert uns an den Code einer Konsolenanwendung, die als Startpunkt der Laufzeit in einer Klasse Program die statische Methode Main enthält. Genauso ist es auch bei einer Windows-Anwendung. Allerdings wird bereits Programmcode vorgegeben, denn schließlich soll dem Anwender das erste Windows-Fenster der Anwendung angezeigt werden und nicht die Konsole.

a
Hinweis   Die Unterdrückung der Anzeige der Konsole erfolgt im Eigenschaftsfenster der Anwendung. Aktivieren Sie die Lasche Anwendung, sehen Sie, dass Ausgabetyp auf Windows-Anwendung und nicht mehr auf Konsolenanwendung eingestellt ist.

Die Nachrichtenschleife und die Methode »Application.Run«

Ein grundlegender Unterschied zwischen einer Konsolen- und einer Windows-Anwendung ist die so genannte Nachrichtenschleife. Als Nachricht ist ein Ereignis zu verstehen. Windows-Programme reagieren auf Ereignisse, und eine Nachrichtenschleife ist sensibilisiert, ununterbrochen auf eingehende Ereignisse zu lauern. Ob es sich um Ereignisse der Maus, der Tastatur oder um Ereignisse von Peripheriegeräten wie beispielsweise den Drucker handelt, spielt keine Rolle.

Beim Starten einer Windows-Anwendung wird nicht automatisch eine Nachrichtenschleife erstellt; das muss ausdrücklich im Programmcode erfolgen. Dazu dient die statische Methode Run der Klasse Application.


Application.Run(new Form1());

Als Argument wird Run eine neue Instanz der Klasse Form1 übergeben. Dabei handelt es sich um das Anwendungsfenster, das in den beiden Dateien Form1.cs und Form1.Designer.cs definiert ist. Beim Aufruf von Run passieren mehrere Dinge:

gp  Es wird eine Nachrichtenschleife gestartet.
gp  Es wird ein Objekt vom Typ Form1 erzeugt.
gp  Das Form-Objekt wird angezeigt.

Jeder Start einer Anwendung hat zur Folge, dass ein neuer Prozess eröffnet wird, der einen Thread hat, in dem sich die Vorgänge der Anwendung abspielen (zumindest solange Sie keinen zusätzlichen Thread erstellen). Eine Nachrichtenschleife ist immer an einen bestimmten Thread gebunden. Durch den Aufruf von Run mit Übergabe einer Form1-Instanz wird die Nachrichtenschleife an den Primärthread der Anwendung und darüber hinaus auch an die Form gebunden. Schließen Sie das Form-Objekt, wird auch die Anwendung beendet. Es handelt sich hierbei gewissermaßen um das Hauptfenster der Anwendung.

Werden aus dem Hauptfenster heraus weitere Fenster geöffnet und das Hauptfenster anschließend geschlossen, wird auch die Laufzeit der Anwendung beendet. Das hat zur Folge, dass automatisch alle anderen noch geöffneten Fenster gleichzeitig geschlossen werden.

Application.Run ist überladen. Sie können auch die parameterlose Variante einsetzen und haben damit erreicht, dass die Lebensdauer der Nachrichtenschleife nicht mehr an die Existenz der Startform gebunden ist.


Form1 frm = new Form1();
frm.Show();
Application.Run();

Jetzt verhält sich die Anwendung ganz anders, denn mit dem Schließen der Form wird die Anwendung nicht beendet. Sie sehen die Form zwar nicht mehr, aber die Nachrichtenschleife lebt weiter und wartet auf Ereignisse, die nicht mehr kommen können.

Im ersten Moment scheint dieses Verhalten ein Handicap zu sein, dennoch ist auch die parameterlose Run-Methode von Bedeutung. Wir werden darauf noch zu sprechen kommen, wenn wir uns mit Windows-Anwendungen beschäftigen, die mehrere Fenster haben.

Das Windows XP-Darstellungsformat

Mit dem Erscheinen von Windows XP ist ein neues Layout in Mode gekommen. Ich muss zugeben, mir gefällt es nicht, und ich ziehe das klassische vor, wie Sie auch an den Abbildungen in diesem Buch erkennen können. Nichtsdestotrotz müssen wir auf das Windows XP-Layout, dessen inoffizieller Name »Luna« lautet, berücksichtigen, um den Anwendern die Möglichkeit zu geben, in den Genuss dieser Oberflächen zu kommen.

Voraussetzung der Darstellung der Steuerelemente im XP-Layout ist der Aufruf der Methode Application.EnableVisualStyles. Das erledigt das Visual Studio 2005 für uns, bevor Application.Run aufgerufen wird. Im Hintergrund wird dem Programm damit mitgeteilt, die Datei comctrl6.dll zu verwenden, die ab Windows XP verfügbar und für das typische XP-Erscheinungsbild der Steuerelemente zuständig ist. In Abbildung 15.6 sehen Sie das Fenster der obigen Windows-Anwendung in zwei Darstellungsformaten: links das von Windows XP, rechts das klassische.

Abbildung
Hier klicken, um das Bild zu vergrößern

Abbildung 15.6   Das Windows XP und das klassische Darstellungsformat


Galileo Computing

15.3.2 Die Dateien »Form1.cs« und »Form1.Designer.cs«  toptop

Mit dem .NET Framework 2.0 wurden partielle Klassen eingeführt, um den Quellcode auf zwei oder mehr Quellcodedateien aufzuteilen. Damit wird die gleichzeitige Bearbeitung derselben Klasse durch mehrere Entwickler möglich. Bei der Implementierung einer Form-Klasse wird ebenfalls eine partielle Klassedefinition bereitgestellt. In unserer ersten Windows-Anwendung ist der Code auf die Dateien Form1.cs und Form1.Designer.cs aufgeteilt.

Entwickeln Sie eine Windows-Anwendung, wird vom Visual Studio 2005 sehr umfangreicher Code automatisch generiert. Dieser steht in erster Linie im Zusammenhang mit dem Layout der Form und der darin enthaltenen Steuerelemente. Dieser Code ist in der Methode InitializeComponent der Datei Form1.Designer.cs zu finden und sieht auszugsweise wie folgt aus:


partial class Form1 {
  /// <summary>
  /// Erforderliche Methode für die Designerunterstützung.
  /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
  /// </summary>
  private void InitializeComponent() {
    this.txtOriginal = new System.Windows.Forms.TextBox();
    this.txtKopie = new System.Windows.Forms.TextBox();
    this.btnKopieren = new System.Windows.Forms.Button();
    this.btnBeenden = new System.Windows.Forms.Button();
    this.SuspendLayout();
    // 
    // txtOriginal
    // 
    this.txtOriginal.Location = new System.Drawing.Point(13, 13);
    this.txtOriginal.Name = "txtOriginal";
    this.txtOriginal.Size = new System.Drawing.Size(127, 20);
    this.txtOriginal.TabIndex = 0;
    // 
    // txtKopie
    // 
    this.txtKopie.Location = new System.Drawing.Point(13, 51);
    this.txtKopie.Name = "txtKopie";
    this.txtKopie.Size = new System.Drawing.Size(127, 20);
    this.txtKopie.TabIndex = 1;
    // 
    // btnKopieren
    // 
    this.btnKopieren.Location = new System.Drawing.Point(171, 13);
    this.btnKopieren.Name = "btnKopieren";
    this.btnKopieren.Size = new System.Drawing.Size(127, 23);
    this.btnKopieren.TabIndex = 2;
    this.btnKopieren.Text = "Kopieren";
    this.btnKopieren.Click += new System.EventHandler(this.btnKopieren_Click);
    ...
  }
  private System.Windows.Forms.TextBox txtOriginal;
  private System.Windows.Forms.TextBox txtKopie;
  private System.Windows.Forms.Button btnKopieren;
  private System.Windows.Forms.Button btnBeenden;
}

In erster Linie handelt es sich um die Eigenschaftseinstellungen der beteiligten Komponenten, die von der Standardvorgabe des jeweiligen Typs abweichen, also objektspezifisch sind. Es sind die Einstellungen, die Sie im Eigenschaftsfenster der Komponente vornehmen und aus der Lage und Größe der Komponente im Designer resultieren. Die Entwicklungsumgebung setzt das selbstständig in den dazu passenden Code um.

Beachten Sie auch bitte unbedingt den XML-Kommentar zu InitializeComponent. Aus eigener Erfahrung kann ich Ihnen nahe legen, diesen zu beherzigen und wirklich keine Änderungen am Code in InitializeComponent vornehmen. Ich kann davon berichten, dass ich meine Ignoranz mit dem Verlust sämtlicher Steuerelemente in einer Form bezahlen musste.

Neben der Initialisierungsmethode werden auf Klassenebene auch alle Steuerelemente standardmäßig private deklariert. Die Initialisierung der Objekte erfolgt innerhalb von InitializeComponent.

Kommen wir nun zum Code in der Datei Form1.cs.


public partial class Form1 : Form {
  public Form1() {
    InitializeComponent();
  }
  // Behandelt das Click-Ereignis der Schaltfläche 'Kopieren'
  private void btnKopieren_Click(object sender, EventArgs e) {
    txtKopie.Text = txtOriginal.Text;
  }
  // Behandelt das Click-Ereignis der Schaltfläche 'Beenden'
  private void btnBeenden_Click(object sender, EventArgs e) {
    Application.Exit();
  }
}

Wir finden einen parameterlosen Konstruktor, aus dem heraus die weiter oben beschriebene Methode InitializeComponent aufgerufen wird, um die Komponenten zu initialisieren und die Starteigenschaften festzulegen. Neben dem Standardkonstruktor sind in Form1.cs alle benutzerdefinierten Methoden implementiert, zu denen natürlich auch die Ereignishandler zu zählen sind. In unserem Beispiel handelt es sich um die Ereignishandler, die beim Klicken auf die beiden Schaltflächen ausgeführt werden sollen: btnKopieren_Click und btnBeenden_Click.

Der Vorteil partieller Klassen wird jetzt auf zweierlei Weise deutlich:

gp  Der benutzerdefinierte Code ist von dem Code, den die Entwicklungsumgebung generiert, getrennt. Dadurch wird der Entwickler nicht so schnell der Verlockung nachgeben, eventuell doch Änderungen in InitializeComponent durchzuführen.
gp  Der wesentliche Teil des Programmcodes, nämlich der benutzerdefinierte, wird überschaubarer, was insbesondere dem Programmieranfänger den Einstieg erleichtert.
 << zurück
  
  Zum Katalog
Zum Katalog: Visual C# 2005
Visual C# 2005
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Fortgeschrittene Programmierung mit Visual C# 2005






 Fortgeschrittene
 Programmierung
 mit Visual C# 2005


Zum Katalog: Einstieg in Visual C# 2005






 Einstieg in
 Visual C# 2005


Zum Katalog: Einstieg in Visual Basic 2005






 Einstieg in
 Visual Basic 2005


Zum Katalog: Visual Basic 2005






 Visual Basic 2005


Zum Katalog: Java ist auch eine Insel






 Java ist auch eine
 Insel


Zum Katalog: Konzepte und Lösungen für Microsoft-Netzwerke






 Konzepte und
 Lösungen für
 Microsoft-Netzwerke


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo








Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de